#include <stdio.h>
#include <stdlib.h>

#include <string.h>
#include <debug.h>
#include <guistub.h>
#include <stdint.h>
#include <raytrace.h>

#define UINT16_MAX (65535)

model3d_t *model = NULL;
uint16_t vmin, vmax;

scene_t *scene = NULL;

void
gui_init( char *filename )
{
  //debug_level = DEBUG_ERR;
  printf("initializing gui %s\n",filename);

  char *rpattern = "center = (%lg, %lg,%lg) radius = %lg color = (%d, %d, %d) opacity = %lg difuse = %lg specular = %lg n = %d\n";
  char *wpattern = "center = (%f, %f,%f) radius = %f color = (%d, %d, %d) opacity = %f difuse = %f specular = %f n = %d\n";

  FILE*fd = fopen( filename, "r" );

  int r,g,b;
  double opacity,difuse,specular;
  double x,y,z,radius;
  int phong;

  assert( fd != NULL );

  scene = scene_new();


  while( 1 ){

    int scan = fscanf(fd, rpattern,
		      &x,
		      &y,
		      &z,
		      &radius,
		      &r,
		      &g,
		      &b,
		      &opacity,
		      &difuse,
		      &specular,
		      &phong
		      );

    if ( scan < 11 ) break;

    printf( wpattern,
	    x,
	    y,
	    z,
	    radius,
	    r,
	    g,
	    b,
	    opacity,
	    difuse,
	    specular,
	    phong
	    );

    sphere_t *sphere;
    color_t color;
    COLOR_FROM_PAIR_RGB( color, r, g, b);

    sphere = sphere_new();
    assert( scene != NULL );

    SPHERE_X( sphere ) = x;
    SPHERE_Y( sphere ) = y;
    SPHERE_Z( sphere ) = z;

    //COLOR_FROM_ARGB( color, COLOR_RED );
    object_init4( OBJECT( sphere ), color, 1 - opacity, 0 );
    OBJECT( sphere )->kd = difuse; // difuse
    OBJECT( sphere )->ks = specular; // specular
    OBJECT( sphere )->nphong = phong; // phongs
    sphere->radius = radius;
    scene_add_object( scene, OBJECT( sphere ) );

  }


  return;

}


void
load_model( char *filename )
{
  printf("loading model\n");

  if ( filename )
    {
      //model = scn_load( filename );
      //find_intensities( model, &vmin, &vmax );
    }
  else
    {
      vmin = 0;
      vmax = UINT16_MAX;
      model = NULL;
    }
}


void
gui_quit( void )
{
}

void
unload_model( void )
{
}


#include <raytrace.h>
#include <camera.h>
#include <debug.h>
#include <visual.h>
#include <scene.h>
#include <sphere.h>
#include <light.h>

#define TODO( str ) printf("TODO : %s\n", str );


surface_t *
gui_display( double rot_x, double rot_y, light_t *l1, light_t * l2 )
{

  surface_t *surface;

  debug_level = DEBUG_DBG;

  int d = 250;

#ifndef _DEBUG

  //visual_init( d, d );

#endif

  surface = surface_new( d, d );

  coord_t pos0 = { 0, 0 };

  //printf("rotx %f roty %f\n",rot_x, rot_y);

  camera_t camera = {
    .center = { .data = { 0 , 0, 500 } },
    .normal = { .data = { 0 , 0, -1 } },
    .distance = 100,
    .rotx = rot_x,
    .roty = rot_y,
    .surface = surface
  };

  //scene_t *scene = scene_new();

  sphere_t *sphere;
  color_t color;


  light_t *light;

  light = light_new();
  assert( light != NULL );

  LIGHT_X( light ) = 400;
  LIGHT_Y( light ) = 0;
  LIGHT_Z( light ) = 400;

  linkedlist_t *ilumination = list_new();

  struct object_node *node;

  node = list_add( ilumination, struct object_node );
  //node->object = ( object_t * )light;
  node->object = ( object_t * )l1;

  light = light_new();
  assert( light != NULL );

  LIGHT_X( light ) = 0;
  LIGHT_Y( light ) = 0;
  LIGHT_Z( light ) = -400;

  node = list_add( ilumination, struct object_node );
  //node->object = ( object_t * )light;
  node->object = ( object_t * )l2;

  light_t *l;
  for_each_list_element( ilumination, node ){
    l = (light_t*)node->object;
    char *str;
    //str = light_str( l );
    //printf("%s\n", str );
    //free( str );
  }

  //scene_raytrace( scene, camera, light );
  scene_raytrace( scene, camera, ilumination );

  return camera.surface;

#ifndef _DEBUG
  visual_display( surface, pos0 );
  visual_update();
  visual_waitkey();
  //return 1;
#else
  return 1;
#endif


}
